﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceProcess;
using System.IO;

namespace MutliServiceController
{
    public partial class FormMain : Form
    {
        List<ServiceItem> services = new List<ServiceItem>();
        private string fileaname = "ServiceList.cfg";
        private bool hideOnLoad;

        private delegate void RefreshItemsInvoker(ServiceItem item);

        public FormMain(bool hideOnLoad)
        {
            InitializeComponent();
            InitContextMenu();
            comboBoxServiceName.DataSource = GetAllServiceName();
            comboBoxServiceName.DisplayMember = "DisplayName";
            this.hideOnLoad = hideOnLoad; 
            //this.Visible = false;
        }

        private void FormMain_Shown(object sender, EventArgs e)
        {
            //this.WindowState = FormWindowState.Normal; 
            //if (this.hideOnLoad)
            this.Hide();
            
            
            LoadFile();            
        }

        #region FileManagement
        public void LoadFile()
        {
            if (File.Exists(this.fileaname))
            {
                TextReader reader = File.OpenText(this.fileaname);
                try
                {
                    string line = reader.ReadLine();
                    while (line != null && line != "")
                    {
                        AddService(line);
                        line = reader.ReadLine();
                    }
                }
                finally
                {
                    reader.Close();
                }
            }
        }

        public void SaveFile()
        {
            TextWriter writer = new StreamWriter(File.Open(this.fileaname, FileMode.Create, FileAccess.Write));
            try
            {
                foreach (ServiceItem item in services)
                {
                    writer.WriteLine(item.ServiceName);
                }
            }
            finally
            {
                writer.Close();
            }
        }
        #endregion

        #region ContextMenu Base
        private void InitContextMenu()
        {
            notifyIcon.ContextMenuStrip = new ContextMenuStrip();

            ToolStripMenuItem openMenu = new ToolStripMenuItem("Open");
            notifyIcon.ContextMenuStrip.Items.Add(openMenu);
            openMenu.Click += new EventHandler(openMenu_Click);

            ToolStripMenuItem exitMenu = new ToolStripMenuItem("Exit");
            notifyIcon.ContextMenuStrip.Items.Add(exitMenu);
            exitMenu.Click += new EventHandler(exitMenu_Click);

            notifyIcon.ContextMenuStrip.Items.Add("-");
        }

        void openMenu_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal; 
        }

        void exitMenu_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        delegate void UpdateMenuStatus(ServiceMenuItem item, ServiceControllerStatus newStatus);

        void UpdateMenuStatusInvoker(ServiceMenuItem item, ServiceControllerStatus newStatus)
        {
            //foreach (ToolStripItem item in this.notifyIcon.ContextMenuStrip.Items)
            //{
            //    if (item.GetType() == typeof(ServiceMenuItem))
            //    {
                    ((ServiceMenuItem)item).UpdateStatus(newStatus);
                //}
            //}
        }

        #endregion

        #region Getting all Services List
        public ServiceController[] GetAllServiceName ()
        {
            //System.ServiceProcess.ServiceController[] svcList;
            //svcList = 
            return System.ServiceProcess.ServiceController.GetServices();
            //List<string> names = new List<string>();
            //foreach (ServiceController s in svcList)
            //{
            //    names.Add(s.ServiceName);
            //}
            //return names.ToArray();
        }
        #endregion

        #region Events handlers
        private void buttonAdd_Click(object sender, EventArgs e)
        {
            if (comboBoxServiceName.Text != "")
            {
                AddService(((ServiceController)comboBoxServiceName.SelectedItem).ServiceName);
                //comboBoxServiceName.Text = "";
                comboBoxServiceName.Focus();
            }            
        }

        void menuItem_OnStatusChanged(ServiceMenuItem sender, ServiceControllerStatus newStatus)
        {
            UpdateMenuStatus updateInvoker = new UpdateMenuStatus(UpdateMenuStatusInvoker);
            this.Invoke(updateInvoker, sender, newStatus);
        }

        void item_OnStatusChanged(ServiceItem item, System.ServiceProcess.ServiceControllerStatus status)
        {
            new RefreshItemsInvoker(RefreshList).Invoke(item);
        }

        private void textBoxServiceName_Enter(object sender, EventArgs e)
        {
            this.AcceptButton = buttonAdd;
        }

        private void textBoxServiceName_Leave(object sender, EventArgs e)
        {
            this.AcceptButton = null;
        }

        private void buttonRemove_Click(object sender, EventArgs e)
        {
            if (listBoxServices.SelectedItem != null)
            {
                ServiceItem service = (ServiceItem)listBoxServices.SelectedItem;

                RemoveService(service);
            }
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            SaveFile();
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            ServiceItem service = (ServiceItem)listBoxServices.SelectedItem;
            if (service != null) 
                service.Start();
        }

        private void buttonStop_Click(object sender, EventArgs e)
        {
            ServiceItem service = (ServiceItem)listBoxServices.SelectedItem;
            if (service != null) 
                service.Stop();
        }

        private void buttonReset_Click(object sender, EventArgs e)
        {
            ServiceItem service = (ServiceItem)listBoxServices.SelectedItem;
            if (service != null)
                service.Reset();
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                this.Hide();
            }
            else
            {
                foreach (ServiceItem service in services)
                {
                    service.Dispose();
                }

                Application.Exit();
            }
        }

        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            this.Show();
        }
        #endregion

        #region List Management
        private void AddService (string serviceName)
        {
            ServiceItem item = new ServiceItem(serviceName);
            services.Add(item);
            listBoxServices.Items.Add(item);
            item.OnStatusChanged += new ServiceItem.OnStatusChanged_Handler(item_OnStatusChanged);
            ServiceMenuItem menuItem = new ServiceMenuItem(item);
            menuItem.OnStatusChanged += new ServiceMenuItem.StatusChangedInvoker(menuItem_OnStatusChanged);
            notifyIcon.ContextMenuStrip.Items.Add(menuItem);
            menuItem.UpdateStatus();
        }

        private void RemoveService(ServiceItem service)
        {
            this.notifyIcon.ContextMenuStrip.Items.Remove(service.MenuItem);
            listBoxServices.Items.Remove(service);
            service.Dispose();
            services.Remove(service);
            service.Dispose();
        }

        private void RefreshList(ServiceItem item)
        {
            if (this.listBoxServices.InvokeRequired)
            {
                RefreshItemsInvoker invoker = new RefreshItemsInvoker(RefreshList);
                this.Invoke(invoker, new object[] { item });
            }
            else
            {
                int pos = listBoxServices.Items.IndexOf(item);
                listBoxServices.Items.Remove(item);
                listBoxServices.Items.Insert(pos, item);
            }

        }
        #endregion
      
    }
}
